
#include "sr.h"

/* bit 0 : alfa
   bit 1 : xl
   bit 2 : xc
   bit 4 : powerOn
   bit 5 : shutdown
   bit 6 : posdesired  */
extern int hasEventFlags;

extern double Alfa;
extern double XC;
extern double posdesired;

/* bit 0 : SWPoscarMin
   bit 1 : SWPoscarmax
   bit 2 : trigger
   bit 3 : emstopCheckPosDesired
   bit 4 : emstopCheckMinMax
   bit 5 : emstopMeger
   bit 6 : emmodeCheckAlfa
   bit 7 : vcControlAlg
   bit 8 : brakeCondition
   bit 9 : isKnown
   bit 10 : Brake
*/
int craneKnownFlags;

/* bit 0 : SWPoscarMin
   bit 1 : SWPoscarmax
   bit 2 : trigger
   bit 3 : emstopCheckPosDesired
   bit 4 : emstopCheckMinMax
   bit 5 : emstopMeger
   bit 6 : emmodeCheckAlfa
   bit 7 : vcControlAlg
   bit 8 : brakeCondition
   bit 9 : isKnown
   bit 10 : Brake
*/
int cranePresentFlags;

extern char Brake;
extern double VC;

// Arestas que carregam dados
char SWPoscarMin;
char SWPoscarMax;
double vcControlAlg;
char brakeCondition;
char isKnown;

extern void initPowerUp(void);
extern void initCheckPosDesired(void);
extern void initCheckMinMaxPos(void);
extern void initCheckAlfa(void);
extern void initControlAlg(void);
extern void initBrakeCondition(void);
extern void initControlBrake(void);

extern void posSensorsFire(double, int, char *, char *, int *, int *);
extern void brakeConditionFire(double, char *, int, int *, int *);
extern void powerUpFire(int, int *, int *);
extern void checkPosDesiredFire(double, int, int *, int *);
extern void checkMinMaxPosFire(char, char, int *, int *);
extern void emstopMergerFire(int *, int *);
extern void checkAlfaFire(double, int, int *, int *);
extern void controlAlgFire(double, double, double, int, double *, int *, int *);
extern void isKnownFire(char *, int *, int *);
extern void controlBrakeFire(double, char, char, char *, int, int *, int *);

extern void powerUpPostfire(int, int, int);
extern void checkPosDesiredPostfire(int, int, int);
extern void checkMinMaxPosPostfire(int, int, int);
extern void checkAlfaPostfire(int, int, int);
extern void brakeConditionPostfire(int, int, int);
extern void controlAlgPostfire(char, int, int, int);
extern void controlBrakePostfire(int, int, int);
    
void
initCrane(void) {

    initPowerUp();
    initCheckPosDesired();
    initCheckMinMaxPos();
    initCheckAlfa();
    initControlAlg();
    initBrakeCondition();
    initControlBrake();
}

void
crane(void) {
    double vcout;
    char brakeout;

    craneKnownFlags = 0;
    cranePresentFlags = 0;

    posSensorsFire(XC, hasEventFlags, &SWPoscarMin, &SWPoscarMax, &craneKnownFlags,
        &cranePresentFlags);

    powerUpFire(hasEventFlags, &craneKnownFlags, &cranePresentFlags);

    checkPosDesiredFire(posdesired, hasEventFlags, &craneKnownFlags, &cranePresentFlags);

    checkMinMaxPosFire(SWPoscarMin, SWPoscarMax, &craneKnownFlags, &cranePresentFlags);

    emstopMergerFire(&craneKnownFlags, &cranePresentFlags);

    checkAlfaFire(Alfa, hasEventFlags, &craneKnownFlags, &cranePresentFlags);

    controlAlgFire(posdesired, XC, Alfa, hasEventFlags, &vcout,
        &craneKnownFlags, &cranePresentFlags);

    brakeConditionFire(vcout, &brakeCondition, hasEventFlags, &craneKnownFlags, 
        &cranePresentFlags);

    isKnownFire(&isKnown, &craneKnownFlags, &cranePresentFlags);

    controlBrakeFire(posdesired, brakeCondition, isKnown, &brakeout, hasEventFlags,
        &craneKnownFlags, &cranePresentFlags);

    // Postfires
    powerUpPostfire(hasEventFlags, craneKnownFlags, cranePresentFlags);
    checkPosDesiredPostfire(hasEventFlags, craneKnownFlags, cranePresentFlags);
    checkMinMaxPosPostfire(hasEventFlags, craneKnownFlags, cranePresentFlags);
    checkAlfaPostfire(hasEventFlags, craneKnownFlags, cranePresentFlags);    
    brakeConditionPostfire(hasEventFlags, craneKnownFlags, cranePresentFlags);
    controlAlgPostfire(brakeout, hasEventFlags, craneKnownFlags, cranePresentFlags);
    controlBrakePostfire(hasEventFlags, craneKnownFlags, cranePresentFlags);

    // comunicao externa
    if(GET_BIT(cranePresentFlags, BRAKEBIT)) {
        Brake = brakeout;
    }
    if(GET_BIT(cranePresentFlags, VCCONTROLALGBIT)) {
        VC = vcout;
    }
}
